package com.jkkc.lib.base.util;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Calendar;

public class HexUtil {

    public enum TimeType {
        RUN50, RUNWANGFAN, TIMESHOW
    }

    /**
     * hex转byte数组
     *
     * @param hex
     * @return
     */
    public static byte[] hexToByte(String hex) {
        int m = 0, n = 0;
        int byteLen = hex.length() / 2; // 每两个字符描述一个字节
        byte[] ret = new byte[byteLen];
        for (int i = 0; i < byteLen; i++) {
            m = i * 2 + 1;
            n = m + 1;
            int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
            ret[i] = Byte.valueOf((byte) intVal);
        }
        return ret;
    }

    public static final String bytesToTen(byte[] b) {
        long res = 0;
        int length = b.length;
        for (int i = length - 1; i >= 0; i--) {
            res = (res << 8) + (b[i] & 0xff);
        }
        return String.format("%010d", res);
    }

    /**
     * byte数组转hex
     *
     * @param bytes
     * @return
     */
    public static String byteToHex(byte[] bytes) {
        String strHex = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < bytes.length; n++) {
            strHex = Integer.toHexString(bytes[n] & 0xFF);
            sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示，位数不够，高位补0
        }
        return sb.toString().trim();
    }

    public static String byteToHex(byte[] bytes, String symbol) {
        String strHex = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < bytes.length; n++) {
            strHex = Integer.toHexString(bytes[n] & 0xFF);
            sb.append((strHex.length() == 1) ? "0" + strHex : strHex).append(symbol); // 每个字节由两个字符表示，位数不够，高位补0
        }
        return sb.toString().trim();
    }

    public static String byteToHexFomat(byte[] bytes, int... ints) {
        String strHex = "";
        StringBuilder sb = new StringBuilder("");
        int size = ints.length;
        int position = 0;
        for (int n = 0; n < bytes.length; n++) {
            strHex = Integer.toHexString(bytes[n] & 0xFF);
            sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示，位数不够，高位补0
            if (position < size) {
                if (n == ints[position]) {
                    position++;
                    sb.append(" ");
                }
            }
        }
        return sb.toString().trim();
    }

    // 实现数组元素的翻转
    public static byte[] reverse(byte[] arr) {
        // 遍历数组
        for (int i = 0; i < arr.length / 2; i++) {
            // 交换元素
            byte temp = arr[arr.length - i - 1];
            arr[arr.length - i - 1] = arr[i];
            arr[i] = temp;
        }
        // 返回反转后的结果
        return arr;
    }

    /**
     * @param data
     * @return 获取电量
     */
    public static float getBattery(byte[] data) {
        //电压字节  0x01d0
        //说明：最后一个数字 ‘ 0 ’ 代表 电压类型   01D  代表电压百分比
        int all = ((data[1] & 0xFF) << 8) + (data[0] & 0xFF);
        int type = all & 0x000F;
        if (type == 0) {
            return ((all >> 4) & 0x0FFF);
        } else {
            return 100 + ((all >> 4) & 0x0FFF) / 100f;
        }
    }

    public static int getRssi(byte rssi) {
        //信号强度RSSI说明：
        //大于0并且小于或等于60为最强信号  信号显示满格
        //大于或者等于120为最弱信号
        int value = rssi;
        if (value > 0 && value <= 60) {
            return 100;
        } else if (value >= 120) {
            return 0;
        } else if (value > 60 && value < 120) {
            return 100 - (100 / 60) * (value - 60);
        } else {
            return 0;
        }
    }


    /**
     * @param data  原始接收的数据,成绩取一位小数
     * @param start 成绩开始位置
     * @param len   成绩长度
     * @return
     */
    public static String getRes(byte[] data, int start, int len) {
        byte[] res = reverse(Arrays.copyOfRange(data, start, start + len));
        int t = 0;
        for (byte b : res) {
            t = (t << 8) + (b & 0xFF);
        }
        BigDecimal decimal = new BigDecimal(t).divide(new BigDecimal(10));
        return decimal.toString();
    }

    public static String getResWithMinus(byte[] data, int start, int len, int base) {
        byte[] res = reverse(Arrays.copyOfRange(data, start, start + len));
        int t = 0;
        for (byte b : res) {
            t = (t << 8) + (b & 0xFF);
        }
        BigDecimal decimal = new BigDecimal(t).divide(new BigDecimal(10)).subtract(new BigDecimal(base));
        return decimal.toString();
    }

    public static String getIntegerRes(byte[] data, int start, int len) {
        byte[] res = reverse(Arrays.copyOfRange(data, start, start + len));
        int t = 0;
        for (byte b : res) {
            t = (t << 8) + (b & 0xFF);
        }
        return String.valueOf(t);
    }

    /**
     * @param host 判断hostID是否为空
     * @return
     */
    public static boolean isHostEmpty(byte[] host) {
        for (byte b : host) {
            if (b != 0) {
                return false;
            }
        }
        return true;
    }


    /**
     * @return 获取当前时间，用于无线模块校准
     */
    public static byte[] getTime() {
        long time = getLongTime();
        byte[] bTime = new byte[4];
        bTime[0] = (byte) (time >> 24);
        bTime[1] = (byte) ((time >> 16) & 0x00FF);
        bTime[2] = (byte) ((time >> 8) & 0x0000FF);
        bTime[3] = (byte) (time & 0x000000FF);
        return reverse(bTime);
    }

    //获取当前时分秒的 毫秒时间
    public static long getLongTime() {
        Calendar now = Calendar.getInstance();
        int hour = now.get(Calendar.HOUR_OF_DAY);
        int min = now.get(Calendar.MINUTE);
        int sec = now.get(Calendar.SECOND);
        int ms = now.get(Calendar.MILLISECOND);
        long time = hour * 3600 * 1000 + min * 60000 + sec * 1000 + ms;
        return time;
    }

    /**
     * @param start 用于显示秒表的时间
     * @return
     */
    public static String getRunTime(long start) {
        if (start == 0) {
            return "00:00.00";
        }
        long time = System.currentTimeMillis() - start;
        return getTimeStr(time);
    }

    public static String getCountDownTime(long start, int countDown) {
        if (start == 0) {
            return "00:00.00";
        }
        long time = countDown * 1000 - (System.currentTimeMillis() - start);
        if (time <= 0) {
            return "00:00.00";
        }
        return getTimeStr(time);
    }


    /**
     * @param power 将无线模块功率设置从int转为byte[]
     * @return
     */
    public static byte[] getPower(int power) {
        byte[] pow = new byte[2];
        pow[0] = (byte) ((power >> 8) & 0x0000FF);
        pow[1] = (byte) (power & 0x000000FF);
        return reverse(pow);
    }


    /**
     * @param ver 获取版本号
     * @return
     */
    public static String getVersion(byte[] ver) {
        if (ver.length == 4) {
            int big = (ver[0] << 8) + ver[1];
            int small = (ver[2] << 8) + ver[3];
            return big + "." + small;
        }
        return "err";
    }

    /**
     * @param data 获取升级文件的长度
     * @return
     */
    public static long getBinSize(byte[] data) {
        long len = 0;
        for (byte b : data) {
            len = (len << 8) + (b & 0xFF);
        }
        return len;
    }

    /**
     * @param start 获取写入升级数据的flash地址
     * @return
     */
    public static byte[] getDDRAddress(long start) {
        byte[] add = new byte[4];
        add[0] = (byte) (start >> 24);
        add[1] = (byte) ((start >> 16) & 0x00FF);
        add[2] = (byte) ((start >> 8) & 0x0000FF);
        add[3] = (byte) (start & 0x000000FF);
        return reverse(add);
    }

    /**
     * 计算跑步类的时间
     *
     * @param data
     * @param resStart
     * @param timeType
     * @return
     */
    public static String getRunRes(byte[] data, long resStart, TimeType timeType) {
        byte[] byts = reverse(Arrays.copyOf(data, 4));
        long total = 0;
        for (byte b : byts) {
            total = (total << 8) + (b & 0xFF);
        }
        total = total - resStart;
        switch (timeType) {
            case RUN50:
                return getTimeStr2(total);
            case RUNWANGFAN:
                return getTimeStr3(total);
            default:
                return getTimeStr(total);
        }
    }

    public static String getRunRes(byte[] data, long resStart, TimeType timeType, int adjustTime) {
        byte[] byts = reverse(Arrays.copyOf(data, 4));
        long total = 0;
        for (byte b : byts) {
            total = (total << 8) + (b & 0xFF);
        }
        total = total - resStart + adjustTime;
        switch (timeType) {
            case RUN50:
                return getTimeStr2(total);
            case RUNWANGFAN:
                return getTimeStr3(total);
            default:
                return getTimeStr(total);
        }
    }

    public static byte[] getStartParameter(long param) {
        byte[] add = new byte[4];
        add[0] = (byte) (param >> 24);
        add[1] = (byte) ((param >> 16) & 0x00FF);
        add[2] = (byte) ((param >> 8) & 0x0000FF);
        add[3] = (byte) (param & 0x000000FF);
        return reverse(add);
    }

    public static byte[] getGunDelay(int t) {
        byte[] data = new byte[2];
        data[0] = (byte) ((t >> 8) & 0x0000FF);
        data[1] = (byte) (t & 0x000000FF);
        return reverse(data);
    }


    public static String timeCompare(byte[] data) {
        long android = getLongTime();
        byte[] byts = reverse(Arrays.copyOf(data, 4));
        long rf = 0;
        for (byte b : byts) {
            rf = (rf << 8) + (b & 0xFF);
        }
        return getTimeStr(android) + " " + getTimeStr(rf) + "误差：" + (android - rf);
    }

    //返回标准时间 03:22.426  分:秒.毫秒
    public static String getTimeStr(long time) {
        int min = (int) (time / (60 * 1000));
        int sec = (int) ((time / 1000) % 60);
        int mill = (int) (time % 1000);
        return String.format("%02d:%02d.%03d", min, sec, mill);
    }

    //返回短跑时间 22.426  秒.毫秒
    public static String getTimeStr2(long time) {
        int sec = (int) ((time / 1000) % 60);
        int mill = (int) (time % 1000);
        return String.format("%02d.%03d", sec, mill);
    }

    public static String getTimeStr3(long time) {
        int min = (int) (time / (60 * 1000));
        int sec = (int) ((time / 1000) % 60);
        return String.format("%02d.%02d", min, sec);
    }

    /**
     * 判断字符是否是汉字
     *
     * @param c 字符
     * @return 是否是汉字
     */
    public static boolean isZH(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
            return true;
        }
        return false;
    }

    public static byte[] charToByte(char c) {
        byte[] b = new byte[2];
        b[0] = (byte) ((c & 0xFF00) >> 8);
        b[1] = (byte) (c & 0xFF);
        return b;
    }

}
